/*
 Copyright (C) 2009 QDSS.org
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.qdss.persist.metadata.impl;

import java.util.HashSet;
import java.util.Set;

import org.qdss.persist.Entity;
import org.qdss.persist.Field;
import org.qdss.persist.dialect.Type;
import org.qdss.persist.metadata.BaseMetaObject;
import org.qdss.persist.metadata.CascadeModel;


/**
 * 
 * 
 * @author <a href="mailto:zhaofang123@gmail.com">FANGFANG ZHAO</a>
 * @since 0.1.0, Feb 4, 2009
 * @version $Id: FieldImpl.java 51 2009-05-06 07:45:48Z zhaofang123@gmail.com $
 */
public class FieldImpl extends BaseMetaObject implements Field, Cloneable {
	private static final long serialVersionUID = 1702329731097027085L;
	
	private Entity ownEntity;
	private Type type;
	private int maxLength;
	private CascadeModel cascadeModel;
	
	private Set<Entity> referenceSet = new HashSet<Entity>();
	
	private boolean nullable;
	private boolean creatable;
	private boolean updatable;
	private boolean repeatable;

	public FieldImpl(String name, String physicalName, boolean biultIn,
			String description, Entity ownEntity, Type type, CascadeModel cascade, int maxLength, boolean n, boolean c, boolean u, boolean r) {
		super(name, physicalName, biultIn, description);

		this.ownEntity = ownEntity;
		this.type = type;
		this.maxLength = maxLength;
		this.cascadeModel = cascade;
		
		this.nullable = n;
		this.creatable = c;
		this.updatable = u;
		this.repeatable = r;
	}
	
	public Entity[] getReferenceList() {
		if (referenceSet.isEmpty())
			return EntityImpl.EMPTY_ENTITY_ARRAY;
		return referenceSet.toArray(new Entity[referenceSet.size()]);
	}
	
	public Entity getOwnEntity() {
		return ownEntity;
	}

	public Type getType() {
		return type;
	}
	
	public CascadeModel getCascadeModel() {
		return cascadeModel;
	}

	public int getMaxLength() {
		return maxLength;
	}
	
	public boolean isCreatable() {
		return creatable;
	}

	public boolean isNullable() {
		return nullable;
	}

	public boolean isRepeatable() {
		return repeatable;
	}

	public boolean isUpdatable() {
		return updatable;
	}

	@Override
	public int hashCode() {
		return (ownEntity.getEntityCode() + getName()).hashCode() >> 13;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj == this)
			return true;
		if (!(obj instanceof FieldImpl))
			return false;
		return ((FieldImpl) obj).hashCode() == hashCode();
	}

	@Override
	public String toString() {
		return '<' + ownEntity.getName() + '#' + getName() + ", "
				+ getType().getMask() + '>';
	}
	
	@Override
	public Object clone() throws CloneNotSupportedException {
		FieldImpl clone = (FieldImpl) super.clone();
		clone.referenceSet = new HashSet<Entity>(this.referenceSet);
		return clone;
	}
	
	protected void addReference(Entity entity) {
		referenceSet.add(entity);
		((EntityImpl) entity).addReferenceTo(this);
	}
}
